package com.rockcent.service;

import com.rockcent.common.domain.enumclass.Whether;
import com.rockcent.common.utils.BigDecimalUtils;
import com.rockcent.helper.MallFundHelper;
import com.rockcent.mall.lib.domain.*;
import com.rockcent.mall.lib.domain.enumclass.*;
import com.rockcent.mall.lib.helper.BaseMerchantFundFlowHelper;
import com.rockcent.mall.lib.helper.CustomerFundFlowHelper;
import com.rockcent.mall.lib.helper.MallFundFlowHelper;
import com.rockcent.mall.lib.repository.*;
import org.apache.tomcat.jni.BIOCallback;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.lang.reflect.Array;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import static com.rockcent.mall.lib.domain.enumclass.MerchantOrderPathType.*;

/**
 * Created by oyhk on 2017/1/16.
 */
@Component
public class FundService {

    private final Logger log = LoggerFactory.getLogger(FundService.class);

    @Autowired
    private MerchantOrderRepository merchantOrderRepository;
    @Autowired
    private MallOrderRepository mallOrderRepository;
    @Autowired
    private MallFundRepository mallFundRepository;
    @Autowired
    private MallFundFlowRepository mallFundFlowRepository;
    @Autowired
    private MerchantFundRepository merchantFundRepository;
    @Autowired
    private MerchantFundFlowRepository merchantFundFlowRepository;
    @Autowired
    private BaseMerchantFundFlowHelper baseMerchantFundFlowHelper;
    @Autowired
    private MerchantOrderItemRepository merchantOrderItemRepository;
    @Autowired
    private CustomerRepository customerRepository;
    @Autowired
    private CustomerFundRepository customerFundRepository;
    @Autowired
    private CustomerFundFlowRepository customerFundFlowRepository;
    @Autowired
    private MarketOrderRepository marketOrderRepository;
    @Autowired
    private MerchantProductRepository merchantProductRepository;

    /**
     * 礼包产品订单核销
     *
     * @param mallOrder             平台订单
     * @param supplierMerchantOrder 供应商订单
     * @param verifyNum             核销数
     */
    public void giftPacketVerify(MallOrder mallOrder, MerchantOrder supplierMerchantOrder, Long verifyNum) {
        if (mallOrder == null) {
            log.warn("======================>平台订单不能为空",log);
            return;
        }
        if (mallOrder.getGiftId() == null) {
            log.warn("======================>非礼包产品核销,不能调用此方法");
            return;
        }
        if (supplierMerchantOrder == null) {
            log.warn("======================>商家订单不能为空",log);
            return;
        }

        List<MerchantOrderItem> supplierMerchantOrderItemList = merchantOrderItemRepository.findByMerchantOrderIdAndMerchantId(supplierMerchantOrder.getId(), supplierMerchantOrder.getMerchantId());

        // 服务订单
        if (supplierMerchantOrder.getOrderType() == OrderType.SERVICE) {
            MerchantOrderItem supplierMerchantOrderItem = supplierMerchantOrderItemList.get(0);
            if (verifyNum == null) { // 当为空时,全部核销
                verifyNum = supplierMerchantOrderItem.getBuyCount();
            }
            if (supplierMerchantOrderItem.getBuyCount() < verifyNum) {
                log.warn("======================>核销数量超过购买总数 merchant_order_num : {}", supplierMerchantOrder.getOrderNum());
                return;
            }

            // 剩余核销数
            Long surplusCount = supplierMerchantOrderItem.getBuyCount() - supplierMerchantOrderItem.getVerifyCount();
            if (surplusCount <= 0L) {
                log.warn("======================>改订单已核销完成,不能再核销了 merchant_order_num : {}", supplierMerchantOrder.getOrderNum());
                return;
            }
            // 当剩余核销数 - 当前核销数 > 0
            supplierMerchantOrder.setStatus(OrderStatus.FINISHED);
            supplierMerchantOrder.setEvaluateStatus(EvaluateStatus.WAIT_EVALUATE);
            if (surplusCount - verifyNum > 0) {
                // 修改订单结算状态、订单状态
                supplierMerchantOrder.setStatus(OrderStatus.PART_USE);
                supplierMerchantOrder.setEvaluateStatus(EvaluateStatus.DEFAULT);
            }

            supplierMerchantOrderItem.setVerifyCount(supplierMerchantOrderItem.getVerifyCount() + verifyNum);
            if (supplierMerchantOrderItem.getPathType() == B2D2C || supplierMerchantOrderItem.getPathType() == B2D2C2C) {
                MerchantOrder distributorMerchantOrder = merchantOrderRepository.findByMarketOrderNumAndMerchantRole(supplierMerchantOrder.getMarketOrderNum(), MerchantOrderMerchantRole.DISTRIBUTOR);
                MarketOrder marketOrder = marketOrderRepository.findByOrderNum(supplierMerchantOrder.getMarketOrderNum());
                marketOrder.setStatus(supplierMerchantOrder.getStatus());
                // 修改分销市场订单状态
                marketOrderRepository.save(marketOrder);
                distributorMerchantOrder.setStatus(supplierMerchantOrder.getStatus());
                distributorMerchantOrder.setSettleStatus(supplierMerchantOrder.getSettleStatus());
                distributorMerchantOrder.setEvaluateStatus(supplierMerchantOrder.getEvaluateStatus()); // 待评价
                // 修改分销商订单状态
                merchantOrderRepository.save(distributorMerchantOrder);
                MerchantOrderItem distributorMerchantOrderItem = merchantOrderItemRepository.findByMarketOrderNumAndMerchantRole(supplierMerchantOrder.getMarketOrderNum(), MerchantOrderMerchantRole.DISTRIBUTOR);
                distributorMerchantOrderItem.setVerifyCount(supplierMerchantOrderItem.getVerifyCount());
                merchantOrderItemRepository.save(distributorMerchantOrderItem);
            }
            merchantOrderItemRepository.save(supplierMerchantOrderItem);
            // 修改供应商订单状态
            merchantOrderRepository.save(supplierMerchantOrder);
            // 更新平台订单状态
            this.updateMallOrderStatus(mallOrder);
        }
        // 实物订单
        if (supplierMerchantOrder.getOrderType() == OrderType.GOODS) {
            // 修改供应商订单状态
            supplierMerchantOrder.setStatus(OrderStatus.FINISHED);
            supplierMerchantOrder.setEvaluateStatus(EvaluateStatus.WAIT_EVALUATE); // 设置待评价
            // 订单项
            for (MerchantOrderItem supplierMerchantOrderItem : supplierMerchantOrderItemList) {
                supplierMerchantOrderItem.setVerifyCount(supplierMerchantOrderItem.getBuyCount());
                if (supplierMerchantOrderItem.getPathType() == B2D2C || supplierMerchantOrderItem.getPathType() == B2D2C2C) {
                    MerchantOrder distributorMerchantOrder = merchantOrderRepository.findByMarketOrderNumAndMerchantRole(supplierMerchantOrder.getMarketOrderNum(), MerchantOrderMerchantRole.DISTRIBUTOR);
                    // 修改分销商订单状态
                    distributorMerchantOrder.setStatus(supplierMerchantOrder.getStatus());
                    distributorMerchantOrder.setEvaluateStatus(supplierMerchantOrder.getEvaluateStatus()); // 设置待评价
                    merchantOrderRepository.save(distributorMerchantOrder);
                    // 分销订单 merchantOrder、merchantOrderItem 是一对一关系
                    List<MerchantOrderItem> distributorMerchantOrderItems = merchantOrderItemRepository.findByMarketOrderNumAndMerchantRoleAndIsDelete(supplierMerchantOrder.getMarketOrderNum(), MerchantOrderMerchantRole.DISTRIBUTOR, Whether.NO);
                    if (null != distributorMerchantOrderItems) {
                        for (MerchantOrderItem distributorMerchantOrderItem : distributorMerchantOrderItems) {
                            distributorMerchantOrderItem.setVerifyCount(supplierMerchantOrderItem.getBuyCount());
                            merchantOrderItemRepository.save(distributorMerchantOrderItem);
                        }

                    }

                }
                merchantOrderItemRepository.save(supplierMerchantOrderItem);
            }


            merchantOrderRepository.save(supplierMerchantOrder);

            // 更新平台订单状态
            this.updateMallOrderStatus(mallOrder);

        }
        this.giftPacketSettled(mallOrder);
    }

    /**
     * 礼包结算
     *
     * @param mallOrder
     */
    private void giftPacketSettled(MallOrder mallOrder) {
        // 判断整个礼包所有订单是否全部完成
        List<MerchantOrder> merchantOrderList = merchantOrderRepository.findByMallOrderIdAndMallId(mallOrder.getId(), mallOrder.getMallId());
        boolean isAllFinished = merchantOrderList.stream().filter(merchantOrder -> merchantOrder.getMerchantRole() != MerchantOrderMerchantRole.DISTRIBUTOR).allMatch(merchantOrder -> merchantOrder.getStatus() == OrderStatus.FINISHED);
        merchantOrderList = merchantOrderList.stream().filter(merchantOrder -> merchantOrder.getMerchantRole() != MerchantOrderMerchantRole.DISTRIBUTOR).collect(Collectors.toList());
        // 所有订单完成后,礼包开始结算
        if (isAllFinished) {
            for (MerchantOrder supplierSettledMerchantOrder : merchantOrderList) {
                try {
                    Thread.sleep(20L);
                } catch (InterruptedException e) {
                    log.error(e.getMessage(),e);
                }
                List<MerchantOrderItem> supplierMerchantOrderItemList = merchantOrderItemRepository.findByMerchantOrderId(supplierSettledMerchantOrder.getId());
                MerchantOrderItem supplierServiceMerchantOrderItem = supplierMerchantOrderItemList.get(0);
                MerchantOrder distributorMerchantOrder = null;
                List<MerchantOrderItem> distributorMerchantOrderItems = null;
                if (supplierSettledMerchantOrder.getSourceType() == MerchantOrderSourceType.MARKET) {
                    distributorMerchantOrder = merchantOrderRepository.findByMarketOrderNumAndMerchantRole(supplierSettledMerchantOrder.getMarketOrderNum(), MerchantOrderMerchantRole.DISTRIBUTOR);
                    distributorMerchantOrderItems = merchantOrderItemRepository.findByMarketOrderNumAndMerchantRoleAndIsDelete(supplierSettledMerchantOrder.getMarketOrderNum(), MerchantOrderMerchantRole.DISTRIBUTOR, Whether.NO);
                }
                if (supplierSettledMerchantOrder.getOrderType() == OrderType.GOODS) {
                    this.productVerifySettled(mallOrder, supplierSettledMerchantOrder, supplierMerchantOrderItemList, distributorMerchantOrder, distributorMerchantOrderItems);
                } else if (supplierSettledMerchantOrder.getOrderType() == OrderType.SERVICE) {
                    this.giftPacketServiceVerifySettled(mallOrder, supplierSettledMerchantOrder, supplierServiceMerchantOrderItem, distributorMerchantOrder, distributorMerchantOrderItems);
                }
            }

            // 当使用现金券 还有剩余现金券金额时，需要把剩余金额从平台冻结金额 转为 平台可用金额
            if (mallOrder.getCashCouponSurplusAmount().compareTo(BigDecimal.ZERO) == 1) {
                MallFund mallFund = mallFundRepository.findOne(mallOrder.getMallFundId());
                // 冻结资金减
                this.mallFundFrozenSubtract(mallFund, mallOrder, mallOrder.getCashCouponSurplusAmount(), FundTransactionFlow.EXPEND, MallFundFlowTransactionType.F_CASH_COUPON_SURPLUS_SUCCESS_FROZEN_EXPEND, null);
                // 可用资金加
                this.mallFundAvailableAmountAdd(mallFund, mallOrder, mallOrder.getCashCouponSurplusAmount(), FundTransactionFlow.INCOME, MallFundFlowTransactionType.F_CASH_COUPON_SURPLUS_SUCCESS_INCOME, null);

            }
        }
    }


    /**
     * 服务核销
     *
     * @param mallOrder             平台订单 结算
     * @param supplierMerchantOrder 商家订单
     * @param verifyNum             核销数
     */
    @Transactional(propagation = Propagation.REQUIRED)
    public void serviceVerify(MallOrder mallOrder, MerchantOrder supplierMerchantOrder, Long verifyNum, boolean isPaymentNotifySettled) {

        log.info("============+==========>服务核销 商家订单号 : {} , 核销数量 : {}", supplierMerchantOrder.getOrderNum(), verifyNum);

        if (supplierMerchantOrder.getOrderType() != OrderType.SERVICE) {
            log.warn("======================>非服务订单不能部分核销 merchant_order_num : {}", supplierMerchantOrder.getOrderNum());
            return;
        }

        List<MerchantOrderItem> merchantOrderItemList = merchantOrderItemRepository.findByMerchantOrderIdAndMerchantId(supplierMerchantOrder.getId(), supplierMerchantOrder.getMerchantId());
        if (merchantOrderItemList.size() == 0) {
            log.warn("======================>订单异常,没有订单项 merchant_order_num : {}", supplierMerchantOrder.getOrderNum());
            return;
        }
        MerchantOrderItem supplierMerchantOrderItem = merchantOrderItemList.get(0);
        if (verifyNum == null) { // 当为空时,全部核销
            verifyNum = supplierMerchantOrderItem.getBuyCount();
        }
        if (supplierMerchantOrderItem.getBuyCount() < verifyNum) {
            log.warn("======================>核销数量超过购买总数 merchant_order_num : {}", supplierMerchantOrder.getOrderNum());
            return;
        }

        // 核销数
        Long verifyCount = supplierMerchantOrderItem.getVerifyCount();
        // 剩余核销数
        Long surplusCount = supplierMerchantOrderItem.getBuyCount() - verifyCount;
        if (surplusCount <= 0L) {
            log.warn("======================>该订单已核销完成,不能再核销了 merchant_order_num : {}", supplierMerchantOrder.getOrderNum());
            return;
        }
        SettlementStatus supplierMerchantOrderSettlementStatusTemp = supplierMerchantOrder.getSettleStatus();

        // 非不可退服务支付成功首次服务核销，需要修改产品核销数
        if (isPaymentNotifySettled) {
            supplierMerchantOrder.setStatus(OrderStatus.WAIT_USE);
        } else {
            // 修改核销数
            supplierMerchantOrderItem.setVerifyCount(verifyCount + verifyNum);
            // 当剩余核销数 - 当前核销数 > 0
            if (surplusCount - verifyNum > 0) {
                // 修改订单结算状态、订单状态
                supplierMerchantOrder.setStatus(OrderStatus.PART_USE);
            } else {
                // 修改订单结算状态、订单状态
                supplierMerchantOrder.setStatus(OrderStatus.FINISHED);
                supplierMerchantOrder.setEvaluateStatus(EvaluateStatus.WAIT_EVALUATE);
            }
        }
        MerchantOrder distributorMerchantOrder = null;
        MerchantOrderItem distributorMerchantOrderItem = null;
        MerchantOrderPathType pathType = supplierMerchantOrderItem.getPathType();
        log.info("======================>pathType:{}", pathType);
        if (pathType == B2D2C || pathType == B2D2C2C) {
            distributorMerchantOrder = merchantOrderRepository.findByMarketOrderNumAndMerchantRole(supplierMerchantOrder.getMarketOrderNum(), MerchantOrderMerchantRole.DISTRIBUTOR);
            MarketOrder marketOrder = marketOrderRepository.findByOrderNum(supplierMerchantOrder.getMarketOrderNum());
            marketOrder.setStatus(supplierMerchantOrder.getStatus());
            // 修改分销市场订单状态
            marketOrderRepository.save(marketOrder);
            distributorMerchantOrder.setStatus(supplierMerchantOrder.getStatus());
            distributorMerchantOrder.setSettleStatus(supplierMerchantOrder.getSettleStatus());
            distributorMerchantOrder.setEvaluateStatus(supplierMerchantOrder.getEvaluateStatus()); // 待评价
            // 修改分销商订单状态
            merchantOrderRepository.save(distributorMerchantOrder);

            List<MerchantOrderItem> distributorMerchantOrderItemList = merchantOrderItemRepository.findByMerchantOrderIdAndMerchantId(distributorMerchantOrder.getId(), distributorMerchantOrder.getMerchantId());

            distributorMerchantOrderItem = distributorMerchantOrderItemList.get(0);
            distributorMerchantOrderItem.setVerifyCount(supplierMerchantOrderItem.getVerifyCount());
            distributorMerchantOrderItem.setSettleStatus(supplierMerchantOrderItem.getSettleStatus());
            merchantOrderItemRepository.save(distributorMerchantOrderItem);
        }
        merchantOrderItemRepository.save(supplierMerchantOrderItem);
        // 修改供应商订单状态
        merchantOrderRepository.save(supplierMerchantOrder);
        // 更新平台订单状态
        this.updateMallOrderStatus(mallOrder);

        // 当服务不可退，并且是结算状态时，证明支付时已经结算
        if (supplierMerchantOrder.getRefundable() == Whether.NO && supplierMerchantOrderSettlementStatusTemp == SettlementStatus.SETTLED) {
            log.info("======================>当服务不可退，并且是结算状态时，证明支付时已经结算:{}");
            return;
        }
        List<MerchantOrderItem> distributorMerchantOrderItems = new ArrayList<>();
        if (null != distributorMerchantOrderItem) {
            distributorMerchantOrderItems = Arrays.asList(distributorMerchantOrderItem);
        }
        log.info("======================>distributorMerchantOrderItems:{}", distributorMerchantOrderItems);
        // 结算
        this.serviceVerifySettled(mallOrder, supplierMerchantOrder, supplierMerchantOrderItem, distributorMerchantOrder, distributorMerchantOrderItems, verifyNum, surplusCount);

    }

    /**
     * 礼包服务结算
     *
     * @param mallOrder                     平台订单
     * @param supplierMerchantOrder         供应商订单
     * @param supplierMerchantOrderItem     供应商订单项
     * @param distributorMerchantOrder      分销商订单
     * @param distributorMerchantOrderItems 分销商订单项
     */
    private void giftPacketServiceVerifySettled(MallOrder mallOrder, MerchantOrder supplierMerchantOrder, MerchantOrderItem supplierMerchantOrderItem, MerchantOrder distributorMerchantOrder, List<MerchantOrderItem> distributorMerchantOrderItems) {

        // 修改结算状态start-------
        supplierMerchantOrder.setSettleStatus(SettlementStatus.SETTLED);
        merchantOrderRepository.save(supplierMerchantOrder);


        // 修改核销数
        supplierMerchantOrderItem.setSettleStatus(supplierMerchantOrder.getSettleStatus());
        supplierMerchantOrderItem.setVerifyCount(supplierMerchantOrderItem.getBuyCount());
        if (SettlementStatus.SETTLED == supplierMerchantOrderItem.getSettleStatus()) {
            supplierMerchantOrderItem.setDateSettled(new Date());
        }
        merchantOrderItemRepository.save(supplierMerchantOrderItem);

        if (distributorMerchantOrder != null) {
            distributorMerchantOrder.setSettleStatus(supplierMerchantOrder.getSettleStatus());
            merchantOrderRepository.save(distributorMerchantOrder);
        }

        if (distributorMerchantOrderItems != null) {
            for (MerchantOrderItem distributorMerchantOrderItem : distributorMerchantOrderItems) {
                distributorMerchantOrderItem.setSettleStatus(supplierMerchantOrder.getSettleStatus());
                distributorMerchantOrderItem.setSettleStatus(supplierMerchantOrder.getSettleStatus());
                distributorMerchantOrderItem.setVerifyCount(supplierMerchantOrderItem.getVerifyCount());
                if (SettlementStatus.SETTLED == distributorMerchantOrderItem.getSettleStatus()) {
                    distributorMerchantOrderItem.setDateSettled(new Date());
                }
                merchantOrderItemRepository.save(distributorMerchantOrderItem);
            }

        }
        // 修改结算状态end-------

        // 下面是资金结算过程
        Long verifyNum = supplierMerchantOrderItem.getBuyCount();
        this.serviceFundSettled(mallOrder, supplierMerchantOrder, supplierMerchantOrderItem, distributorMerchantOrder, distributorMerchantOrderItems, verifyNum, verifyNum);
    }

    /**
     * 服务订单结算
     *
     * @param mallOrder                 平台订单
     * @param supplierMerchantOrder     供应商家订单
     * @param supplierMerchantOrderItem 供应商家订单项
     * @param distributorMerchantOrder  分销商订单
     * @param verifyNum                 核销数
     */
    private void serviceVerifySettled(MallOrder mallOrder, MerchantOrder supplierMerchantOrder, MerchantOrderItem supplierMerchantOrderItem, MerchantOrder distributorMerchantOrder, List<MerchantOrderItem> distributorMerchantOrderItems, Long verifyNum, Long surplusCount) {


        // 修改结算状态start-------
        supplierMerchantOrder.setSettleStatus(SettlementStatus.SETTLED);
        // 当剩余核销数 - 当前核销数 > 0
        if (surplusCount - verifyNum > 0) {
            // 修改订单结算状态、订单状态
            supplierMerchantOrder.setSettleStatus(SettlementStatus.PART_SETTLE);
        }
        merchantOrderRepository.save(supplierMerchantOrder);

        supplierMerchantOrderItem.setSettleStatus(supplierMerchantOrder.getSettleStatus());
        if (SettlementStatus.SETTLED == supplierMerchantOrderItem.getSettleStatus()) {
            supplierMerchantOrderItem.setDateSettled(new Date());
        }
        merchantOrderItemRepository.save(supplierMerchantOrderItem);

        if (distributorMerchantOrder != null) {
            distributorMerchantOrder.setSettleStatus(supplierMerchantOrder.getSettleStatus());
            merchantOrderRepository.save(distributorMerchantOrder);
        }
        if (distributorMerchantOrderItems != null && 0 < distributorMerchantOrderItems.size()) {
            for (MerchantOrderItem distributorMerchantOrderItem : distributorMerchantOrderItems) {
                distributorMerchantOrderItem.setSettleStatus(supplierMerchantOrder.getSettleStatus());
                distributorMerchantOrderItem.setVerifyCount(supplierMerchantOrderItem.getVerifyCount());
                if (SettlementStatus.SETTLED == distributorMerchantOrderItem.getSettleStatus()) {
                    distributorMerchantOrderItem.setDateSettled(new Date());
                }
                merchantOrderItemRepository.save(distributorMerchantOrderItem);
            }

        }
        // 修改结算状态end-------

        // 资金结算过程
        this.serviceFundSettled(mallOrder, supplierMerchantOrder, supplierMerchantOrderItem, distributorMerchantOrder, distributorMerchantOrderItems, verifyNum, surplusCount);
    }

    /**
     * 资金结算
     *
     * @param mallOrder                     平台订单
     * @param supplierMerchantOrder         供应商家订单
     * @param supplierMerchantOrderItem     供应商家订单项
     * @param distributorMerchantOrder      分销商订单
     * @param distributorMerchantOrderItems 分销商订单项
     * @param verifyNum
     * @param surplusCount
     */
    private void serviceFundSettled(MallOrder mallOrder, MerchantOrder supplierMerchantOrder, MerchantOrderItem supplierMerchantOrderItem, MerchantOrder distributorMerchantOrder, List<MerchantOrderItem> distributorMerchantOrderItems, Long verifyNum, Long surplusCount) {
        BigDecimal verifyRate = new BigDecimal(verifyNum.doubleValue() / supplierMerchantOrderItem.getBuyCount().doubleValue() + "");
        MallFund mallFund;
        //由于悲观锁原因
        if (mallOrder.getGiftId() == null && supplierMerchantOrderItem.getProductRefundable() == Whether.YES) {
            mallFund = mallFundRepository.findByMallId(mallOrder.getMallId());
        } else {
            mallFund = mallFundRepository.findOne(mallOrder.getMallFundId());
        }


        MerchantFund supplierMerchantFund = merchantFundRepository.findOne(supplierMerchantOrder.getMerchantFundId());
        log.info("supplierMerchantFund:{}", supplierMerchantFund);
        // 核销金额
        BigDecimal operationAmount = supplierMerchantOrderItem.getDiscountAmount().multiply(verifyRate).setScale(2, BigDecimal.ROUND_HALF_UP);
        BigDecimal mallServiceFeeRates = BigDecimalUtils.divide(mallOrder.getMallServiceFeeRates(), "100");
        BigDecimal serviceFee = operationAmount.multiply(mallServiceFeeRates).setScale(2, BigDecimal.ROUND_HALF_UP);
        log.info("operationAmount:{},mallServiceFeeRates:{},serviceFee:{}", operationAmount, mallServiceFeeRates, serviceFee);
        log.info("distributorMerchantOrderItems:{}", distributorMerchantOrderItems);
        //礼包情况下,因为添加礼包时,分销商可以设置新售价
        if (distributorMerchantOrderItems != null && 0 < distributorMerchantOrderItems.size()) {
            operationAmount = BigDecimal.valueOf(0);
            for (MerchantOrderItem distributorMerchantOrderItem : distributorMerchantOrderItems) {
                operationAmount = operationAmount.add(distributorMerchantOrderItem.getDiscountAmount().multiply(verifyRate).setScale(2, BigDecimal.ROUND_HALF_UP));
            }

        }
        log.info("operationAmount:{},mallServiceFeeRates:{},serviceFee:{}", operationAmount, mallServiceFeeRates, serviceFee);

        // 平台冻结资金 减
        MallFundFlow parentMallFundFlow = this.mallFundFrozenSubtract(mallFund, mallOrder, operationAmount, FundTransactionFlow.EXPEND, MallFundFlowTransactionType.F_MERCHANT_SETTLEMENT, null);
        // 平台可用资金 加
        this.mallFundAvailableAmountAdd(mallFund, mallOrder, serviceFee, FundTransactionFlow.INCOME, MallFundFlowTransactionType.A_SERVICE_FEE, parentMallFundFlow.getId());

        this.mallFundFrozenSubtract(mallFund, mallOrder, serviceFee, FundTransactionFlow.SPLIT, MallFundFlowTransactionType.A_SERVICE_FEE, parentMallFundFlow.getParentId());

        // 供应商订单结算 订单收入
        MerchantFundFlow supplierMerchantFundFlow = this.merchantFundAvailableAmount(supplierMerchantFund, supplierMerchantOrder, supplierMerchantOrderItem.getDiscountAmount().multiply(verifyRate).setScale(2, BigDecimal.ROUND_HALF_UP), verifyNum, FundTransactionFlow.INCOME, MerchantFundFlowTransactionType.A_ORDER_SETTLEMENT_INCOME, null);
//
//        // 供商家订单结算 平台服务费 减
//        this.merchantFundAvailableAmount(supplierMerchantFund, supplierMerchantOrder, serviceFee, null, FundTransactionFlow.EXPEND, MerchantFundFlowTransactionType.A_ORDER_SERVICE_FEE_EXPEND, supplierMerchantFundFlow.getParentId());
//        merchantFundRepository.save(supplierMerchantFund);

        Long parentId = supplierMerchantFundFlow.getParentId();
        //订单结算收入为0
        boolean isEnough = true;
        //商家纯收入
        BigDecimal merchantIncome = parentMallFundFlow.getOperationAmount();
        BigDecimal lestOrderAmount = operationAmount;
        log.info("merchantIncome:{},lestOrderAmount:{}", merchantIncome, lestOrderAmount);
        //订单结算收入为0
        boolean isCreateNewMerchantFundFlowOfOderAmountOfZero = true;
        BigDecimal mallExpendSplitResellFee = supplierMerchantOrderItem.getResellFee().multiply(verifyRate);//平台支出拆分佣金
        MallFundFlow distributorResellFee = null;//平台支出返利和佣金
        if (supplierMerchantOrderItem.getPathType() == B2D2C || supplierMerchantOrderItem.getPathType() == B2D2C2C) {
            // 计算佣金
            BigDecimal resellFee = supplierMerchantOrderItem.getResellFee().multiply(verifyRate).setScale(2, BigDecimal.ROUND_HALF_UP);
//            // 供商家订单结算 佣金支出
//            this.merchantFundAvailableAmount(supplierMerchantFund, supplierMerchantOrder, resellFee, null, FundTransactionFlow.EXPEND, MerchantFundFlowTransactionType.A_ORDER_RESELL_FEE_EXPEND, supplierMerchantFundFlow.getParentId());
//            merchantFundRepository.save(supplierMerchantFund);

            BigDecimal distributorPacketResellFee = resellFee;
            isEnough = createEnoughToDeductionRecord(lestOrderAmount, resellFee, isEnough, supplierMerchantFund, supplierMerchantOrder, parentId, MerchantFundFlowTransactionType.A_ORDER_RESELL_FEE_EXPEND);
            lestOrderAmount = lestOrderAmount.subtract(distributorPacketResellFee);
            // 分销商家资金
            MerchantFund distributorMerchantFund = merchantFundRepository.findOne(distributorMerchantOrder.getMerchantFundId());

            //礼包情况下,因为添加礼包时,分销商可以设置新售价
            if (distributorMerchantOrderItems != null) {
                distributorPacketResellFee = BigDecimal.valueOf(0);
                for (MerchantOrderItem distributorMerchantOrderItem : distributorMerchantOrderItems) {
                    distributorPacketResellFee = distributorPacketResellFee.add(distributorMerchantOrderItem.getResellFee().multiply(verifyRate));
                }

            }
            if (supplierMerchantOrderItem.getPathType() == B2D2C2C) {
                BigDecimal shareFee = BigDecimal.valueOf(0);
                for (MerchantOrderItem distributorMerchantOrderItem : distributorMerchantOrderItems) {
                    shareFee = shareFee.add(distributorMerchantOrderItem.getShareFee().multiply(verifyRate));
                }
                mallExpendSplitResellFee = distributorPacketResellFee;
//                distributorPacketResellFee = distributorPacketResellFee.subtract(shareFee);
            }
            merchantIncome = merchantIncome.subtract(distributorPacketResellFee);
            lestOrderAmount = lestOrderAmount.subtract(distributorPacketResellFee);

            // 分销商 佣金收入
            this.merchantFundAvailableAmount(distributorMerchantFund, distributorMerchantOrder, distributorPacketResellFee, verifyNum, FundTransactionFlow.INCOME, MerchantFundFlowTransactionType.A_ORDER_RESELL_FEE_INCOME, supplierMerchantFundFlow.getParentId());
            merchantFundRepository.save(distributorMerchantFund);

            distributorResellFee = this.mallFundFrozenSubtract(mallFund, mallOrder, distributorPacketResellFee, FundTransactionFlow.SPLIT, MallFundFlowTransactionType.RESELL_FEE_EXPEND, parentMallFundFlow.getParentId());
        }

        if (supplierMerchantOrderItem.getPathType() == B2C2C) {
            // 分享返利金额
            BigDecimal shareFee = supplierMerchantOrderItem.getShareFee().multiply(verifyRate);
            // 分享返利比率
            BigDecimal shareFeeRates = BigDecimalUtils.divide(supplierMerchantOrderItem.getShareRate(), "100");
            // 供商家订单结算 分享返利支出
            isEnough = createEnoughToDeductionRecord(lestOrderAmount, shareFee, isEnough, supplierMerchantFund, supplierMerchantOrder, parentId, MerchantFundFlowTransactionType.A_ORDER_SHARE_FEE_EXPEND);
            lestOrderAmount = lestOrderAmount.subtract(shareFee);

            // 购买者
            BigDecimal shareCustomerShareFee = shareFee.multiply(shareFeeRates).setScale(2, BigDecimal.ROUND_HALF_UP); // 分享者分享返利
            BigDecimal buyCustomerShareFee = shareFee.subtract(shareCustomerShareFee);// 购买者分享返利

            // 分享者资金 分享返利收入
            Customer shareCustomer = customerRepository.findOne(supplierMerchantOrderItem.getSharerId());
            CustomerFund shareCustomerFund = customerFundRepository.findOne(shareCustomer.getCustomerFundId());
            shareCustomerFund = this.customerFundAvailableAmountAdd(shareCustomerFund, mallOrder, shareCustomerShareFee);
            customerFundRepository.save(shareCustomerFund);
            this.mallFundFrozenSubtract(mallFund, mallOrder, shareCustomerShareFee, FundTransactionFlow.SPLIT, MallFundFlowTransactionType.SHARER_FEE_EXPEND, parentMallFundFlow.getParentId());

            // 购买者资金 分享返利收入
            Customer buyCustomer = customerRepository.findByIdAndMallId(mallOrder.getCustomerId(), mallOrder.getMallId());
            CustomerFund buyCustomerFund;
            //由于悲观锁原因
            if (mallOrder.getGiftId() == null && supplierMerchantOrderItem.getProductRefundable() == Whether.YES) {
                buyCustomerFund = customerFundRepository.findByCustomerIdAndIsDelete(buyCustomer.getId(), Whether.NO);
            } else {
                buyCustomerFund = customerFundRepository.findOne(buyCustomer.getCustomerFundId());
            }

            buyCustomerFund = this.customerFundAvailableAmountAdd(buyCustomerFund, mallOrder, buyCustomerShareFee);
            customerFundRepository.save(buyCustomerFund);
            this.mallFundFrozenSubtract(mallFund, mallOrder, buyCustomerShareFee, FundTransactionFlow.SPLIT, MallFundFlowTransactionType.BUYER_FEE_EXPEND, parentMallFundFlow.getParentId());
            merchantIncome = merchantIncome.subtract(shareFee);
//            lestOrderAmount = lestOrderAmount.subtract(shareFee);
//            isEnough = createEnoughToDeductionRecord(lestOrderAmount, shareFee, isEnough, supplierMerchantFund, supplierMerchantOrder, parentId, MerchantFundFlowTransactionType.A_ORDER_SHARE_FEE_EXPEND);


        } else if (supplierMerchantOrderItem.getPathType() == B2D2C2C) {
            Long productId = supplierMerchantOrderItem.getProductId();
            Product product = merchantProductRepository.findByMarketIdAndMerchantId(productId, distributorMerchantOrder.getMerchantId());
            MerchantOrderItem distributorMerchantOrderItem = merchantOrderItemRepository.findByMarketOrderNumAndMerchantRoleAndProductId(distributorMerchantOrder.getMarketOrderNum(), MerchantOrderMerchantRole.DISTRIBUTOR, product.getId());

//            List<MerchantOrderItem> distributorMerchantOrderItemList = merchantOrderItemRepository.findByMerchantOrderIdAndMerchantId(distributorMerchantOrder.getId(), distributorMerchantOrder.getMerchantId());
            MerchantFund distributorMerchantFund = merchantFundRepository.findOne(distributorMerchantOrder.getMerchantFundId());
            // 分享返利金额
            BigDecimal shareFee = distributorMerchantOrderItem.getShareFee().multiply(verifyRate).setScale(2, BigDecimal.ROUND_HALF_UP);
            // 分享返利比率
            BigDecimal shareFeeRates = BigDecimalUtils.divide(new BigDecimal(distributorMerchantOrderItem.getShareRate()), BigDecimal.valueOf(100));
            // 分商家订单结算 分享返利支出
            this.merchantFundAvailableAmount(distributorMerchantFund, distributorMerchantOrder, shareFee, null, FundTransactionFlow.EXPEND, MerchantFundFlowTransactionType.A_ORDER_SHARE_FEE_EXPEND, supplierMerchantFundFlow.getParentId());
            merchantFundRepository.save(distributorMerchantFund);

            // 购买者
            BigDecimal shareCustomerShareFee = shareFee.multiply(shareFeeRates).setScale(2, BigDecimal.ROUND_HALF_UP); // 分享者分享返利
            BigDecimal buyCustomerShareFee = shareFee.subtract(shareCustomerShareFee);// 购买者分享返利

            // 分享者资金 分享返利收入
            Customer shareCustomer = customerRepository.findOne(distributorMerchantOrderItem.getSharerId());
            CustomerFund shareCustomerFund = customerFundRepository.findOne(shareCustomer.getCustomerFundId());
            shareCustomerFund = this.customerFundAvailableAmountAdd(shareCustomerFund, mallOrder, shareCustomerShareFee);
            customerFundRepository.save(shareCustomerFund);
            this.mallFundFrozenSubtract(mallFund, mallOrder, shareCustomerShareFee, FundTransactionFlow.SPLIT, MallFundFlowTransactionType.SHARER_FEE_EXPEND, parentMallFundFlow.getParentId());

            // 购买者资金 分享返利收入
            Customer buyCustomer = customerRepository.findByIdAndMallId(mallOrder.getCustomerId(), mallOrder.getMallId());
            CustomerFund buyCustomerFund;
            //由于悲观锁原因
            if (mallOrder.getGiftId() == null && supplierMerchantOrderItem.getProductRefundable() == Whether.YES) {
                buyCustomerFund = customerFundRepository.findByCustomerIdAndIsDelete(buyCustomer.getId(), Whether.NO);
            } else {
                buyCustomerFund = customerFundRepository.findOne(buyCustomer.getCustomerFundId());
            }
            buyCustomerFund = this.customerFundAvailableAmountAdd(buyCustomerFund, mallOrder, buyCustomerShareFee);
            customerFundRepository.save(buyCustomerFund);
            this.mallFundFrozenSubtract(mallFund, mallOrder, buyCustomerShareFee, FundTransactionFlow.SPLIT, MallFundFlowTransactionType.BUYER_FEE_EXPEND, parentMallFundFlow.getParentId());
            mallExpendSplitResellFee = mallExpendSplitResellFee.subtract(shareFee);
            if (distributorResellFee != null) {
                distributorResellFee.setOperationAmount(mallExpendSplitResellFee);
                mallFundFlowRepository.save(distributorResellFee);
            }
            merchantIncome = merchantIncome.subtract(shareFee);
//            lestOrderAmount = lestOrderAmount.subtract(shareFee);
        }


        BigDecimal itemServiceFee = supplierMerchantOrderItem.getDiscountAmount().multiply(mallServiceFeeRates).setScale(2, BigDecimal.ROUND_HALF_UP);
        isEnough = createEnoughToDeductionRecord(lestOrderAmount, itemServiceFee, isEnough, supplierMerchantFund, supplierMerchantOrder, parentId,  MerchantFundFlowTransactionType.A_ORDER_SERVICE_FEE_EXPEND);
        log.info("===========+{}+===========>serviceFee:{},merchantIncome:{},itemServiceFee:{},lestOrderAmount:{}", 1, serviceFee, merchantIncome, itemServiceFee, lestOrderAmount);
        lestOrderAmount = lestOrderAmount.subtract(itemServiceFee);
        log.info("===========+{}+===========>serviceFee:{},merchantIncome:{},itemServiceFee:{},lestOrderAmount:{}", 2, serviceFee, merchantIncome, itemServiceFee, lestOrderAmount);

        if (!isEnough) {
            if (lestOrderAmount.compareTo(BigDecimal.valueOf(0)) == -1) {
                lestOrderAmount = new BigDecimal(Math.abs(lestOrderAmount.doubleValue()));
                this.merchantFundAvailableAmount(supplierMerchantFund, supplierMerchantOrder, lestOrderAmount, null, FundTransactionFlow.EXPEND, MerchantFundFlowTransactionType.A_ORDER_SERVICE_FEE_ARREARS_EXPEND, parentId);
            }
        }


        this.mallFundFrozenSubtract(mallFund, mallOrder, merchantIncome.subtract(serviceFee), FundTransactionFlow.SPLIT, MallFundFlowTransactionType.F_MERCHANT_SETTLEMENT, parentMallFundFlow.getParentId());

        // 现金券
        this.cashCouponSurplusAmount(mallOrder, mallFund);
        mallFundRepository.save(mallFund); // 最终保存平台资金
    }

    /**
     * 商品核销 结算
     *
     * @param mallOrder             平台订单
     * @param supplierMerchantOrder 供应商订单
     */
    @Transactional(propagation = Propagation.REQUIRED)
    public void productVerify(MallOrder mallOrder, MerchantOrder supplierMerchantOrder) {
        if (supplierMerchantOrder.getOrderType() != OrderType.GOODS) {
            log.warn("======================>服务订单不能调用此方法结算");
            return;
        }

        MerchantOrder distributorMerchantOrder = null;
        List<MerchantOrderItem> distributorMerchantOrderItems = null;
        // 订单项
        List<MerchantOrderItem> supplierMerchantOrderItemList = merchantOrderItemRepository.findByMerchantOrderIdAndMerchantId(supplierMerchantOrder.getId(), supplierMerchantOrder.getMerchantId());
        for (MerchantOrderItem supplierMerchantOrderItem : supplierMerchantOrderItemList) {
            supplierMerchantOrderItem.setVerifyCount(supplierMerchantOrderItem.getBuyCount());
            if (supplierMerchantOrderItem.getPathType() == B2D2C || supplierMerchantOrderItem.getPathType() == B2D2C2C) {
                distributorMerchantOrder = merchantOrderRepository.findByMarketOrderNumAndMerchantRole(supplierMerchantOrder.getMarketOrderNum(), MerchantOrderMerchantRole.DISTRIBUTOR);
                // 修改分销商订单状态
                distributorMerchantOrder.setStatus(OrderStatus.FINISHED);
                distributorMerchantOrder.setEvaluateStatus(EvaluateStatus.WAIT_EVALUATE);
                merchantOrderRepository.save(distributorMerchantOrder);
                // 分销订单 merchantOrder、merchantOrderItem 是一对一关系
                distributorMerchantOrderItems = merchantOrderItemRepository.findByMarketOrderNumAndMerchantRoleAndIsDelete(supplierMerchantOrder.getMarketOrderNum(), MerchantOrderMerchantRole.DISTRIBUTOR, Whether.NO);
                for (MerchantOrderItem distributorMerchantOrderItem : distributorMerchantOrderItems) {
                    distributorMerchantOrderItem.setVerifyCount(supplierMerchantOrderItem.getBuyCount());
                    merchantOrderItemRepository.save(distributorMerchantOrderItem);
                }

            }
            merchantOrderItemRepository.save(supplierMerchantOrderItem);
        }

        // 修改供应商订单状态
        supplierMerchantOrder.setStatus(OrderStatus.FINISHED);
        supplierMerchantOrder.setEvaluateStatus(EvaluateStatus.WAIT_EVALUATE); // 设置待评价
        merchantOrderRepository.save(supplierMerchantOrder);

        // 更新平台订单状态
        this.updateMallOrderStatus(mallOrder);

        // 结算
        this.productVerifySettled(mallOrder, supplierMerchantOrder, supplierMerchantOrderItemList, distributorMerchantOrder, distributorMerchantOrderItems);

    }


    /**
     * 产品核销结算
     *
     * @param mallOrder                     平台订单
     * @param supplierMerchantOrder         供应商家订单
     * @param supplierMerchantOrderItemList 供应商家订单项
     * @param distributorMerchantOrder      分销商家订单
     */
    private void productVerifySettled(MallOrder mallOrder, MerchantOrder supplierMerchantOrder, List<MerchantOrderItem> supplierMerchantOrderItemList, MerchantOrder distributorMerchantOrder, List<MerchantOrderItem> distributorMerchantOrderItems) {


        // 修改产品结算状态start
        supplierMerchantOrder.setSettleStatus(SettlementStatus.SETTLED);
        merchantOrderRepository.save(supplierMerchantOrder);

        supplierMerchantOrderItemList.forEach(merchantOrderItem -> {
            merchantOrderItem.setSettleStatus(SettlementStatus.SETTLED);
            merchantOrderItem.setVerifyCount(merchantOrderItem.getBuyCount());
            merchantOrderItem.setDateSettled(new Date());
            merchantOrderItemRepository.save(merchantOrderItem);
        });

        if (distributorMerchantOrder != null) {
            distributorMerchantOrder.setSettleStatus(SettlementStatus.SETTLED);
            merchantOrderRepository.save(distributorMerchantOrder);
        }
        if (null != distributorMerchantOrderItems) {
            distributorMerchantOrderItems.forEach(distributorMerchantOrderItem -> {
                if (distributorMerchantOrderItem != null) {
                    distributorMerchantOrderItem.setSettleStatus(SettlementStatus.SETTLED);
                    distributorMerchantOrderItem.setVerifyCount(distributorMerchantOrderItem.getBuyCount());
                    distributorMerchantOrderItem.setDateSettled(new Date());
                    merchantOrderItemRepository.save(distributorMerchantOrderItem);
                }
            });
        }


        // 修改产品结算状态end


        MallFund mallFund = mallFundRepository.findOne(mallOrder.getMallFundId());
        MerchantFund supplierMerchantFund = merchantFundRepository.findOne(supplierMerchantOrder.getMerchantFundId());
        // 核销金额
        BigDecimal operationAmount = supplierMerchantOrder.getDiscountAmount().setScale(2, BigDecimal.ROUND_HALF_UP);
        BigDecimal mallServiceFeeRates = BigDecimalUtils.divide(new BigDecimal(mallOrder.getMallServiceFeeRates()), BigDecimal.valueOf(100));
        BigDecimal serviceFee = operationAmount.multiply(mallServiceFeeRates).setScale(2, BigDecimal.ROUND_HALF_UP);
        //礼包情况下,因为添加礼包时,分销商可以设置新售价
        if (distributorMerchantOrderItems != null) {
            if (distributorMerchantOrderItems != null && 0 < distributorMerchantOrderItems.size()) {
                operationAmount = BigDecimal.valueOf(0);
                for (MerchantOrderItem distributorMerchantOrderItem : distributorMerchantOrderItems) {
                    operationAmount = operationAmount.add(distributorMerchantOrderItem.getDiscountAmount().setScale(2, BigDecimal.ROUND_HALF_UP));
                }
            }

        }


        // 平台冻结资金减
        MallFundFlow parentMallFundFlow = this.mallFundFrozenSubtract(mallFund, mallOrder, operationAmount, FundTransactionFlow.EXPEND, MallFundFlowTransactionType.F_MERCHANT_SETTLEMENT, null);
        // 平台可用资金加
        this.mallFundAvailableAmountAdd(mallFund, mallOrder, serviceFee, FundTransactionFlow.INCOME, MallFundFlowTransactionType.A_SERVICE_FEE, parentMallFundFlow.getId());

        this.mallFundFrozenSubtract(mallFund, mallOrder, serviceFee, FundTransactionFlow.SPLIT, MallFundFlowTransactionType.A_SERVICE_FEE, parentMallFundFlow.getParentId());

        // 供商家可用资金加 订单收入 加
        MerchantFundFlow supplierMerchantFundFlow = this.merchantFundAvailableAmount(supplierMerchantFund, supplierMerchantOrder, supplierMerchantOrder.getDiscountAmount().setScale(2, BigDecimal.ROUND_HALF_UP), null, FundTransactionFlow.INCOME, MerchantFundFlowTransactionType.A_ORDER_SETTLEMENT_INCOME, null);
        Long parentId = supplierMerchantFundFlow.getParentId();
        //订单结算收入为0
        boolean isEnough = true;
        //商家纯收入
        BigDecimal merchantIncome = parentMallFundFlow.getOperationAmount();
        BigDecimal lestOrderAmount = operationAmount;
        log.info("merchantIncome:{},lestOrderAmount:{}", merchantIncome, lestOrderAmount);

        for (MerchantOrderItem supplierMerchantOrderItem : supplierMerchantOrderItemList) {

            BigDecimal mallExpendSplitResellFee = supplierMerchantOrderItem.getResellFee();//平台支出拆分佣金
            MallFundFlow distributorResellFee = null;
            MerchantFundFlowTransactionType feeType = null;
            //平台支出返利和佣金
            if (supplierMerchantOrderItem.getPathType() == B2D2C || supplierMerchantOrderItem.getPathType() == B2D2C2C) {
                // 计算佣金
                BigDecimal resellFee = supplierMerchantOrderItem.getResellFee().setScale(2, BigDecimal.ROUND_HALF_UP);
                log.info("resellFee:{}", resellFee);

                BigDecimal distributorPacketResellFee = resellFee;
                isEnough = createEnoughToDeductionRecord(lestOrderAmount, resellFee, isEnough, supplierMerchantFund, supplierMerchantOrder, parentId, MerchantFundFlowTransactionType.A_ORDER_RESELL_FEE_EXPEND);
                lestOrderAmount = lestOrderAmount.subtract(distributorPacketResellFee);


                // 分销商家资金
                MerchantFund distributorMerchantFund = merchantFundRepository.findOne(distributorMerchantOrder.getMerchantFundId());
                Long productId = supplierMerchantOrderItem.getProductId();
                Product product = merchantProductRepository.findByMarketIdAndMerchantId(productId, distributorMerchantOrder.getMerchantId());
                MerchantOrderItem distributorMerchantOrderItem = merchantOrderItemRepository.findByMarketOrderNumAndMerchantRoleAndProductId(distributorMerchantOrder.getMarketOrderNum(), MerchantOrderMerchantRole.DISTRIBUTOR, product.getId());

                //TODO 礼包情况下,因为添加礼包时,分销商可以设置新售价
//                if (supplierMerchantOrderItem.getPathType() == B2D2C2C) {
//                    BigDecimal shareFee = BigDecimal.valueOf(0);
//                    distributorPacketResellFee = distributorMerchantOrderItem.getShareFee().setScale(2, BigDecimal.ROUND_HALF_UP);
//                    mallExpendSplitResellFee = distributorPacketResellFee;
////                    distributorPacketResellFee = distributorPacketResellFee.subtract(shareFee);
//                }


                merchantIncome = merchantIncome.subtract(distributorPacketResellFee);

                // 分销商 佣金收入
                this.merchantFundAvailableAmount(distributorMerchantFund, distributorMerchantOrder, distributorPacketResellFee, null, FundTransactionFlow.INCOME, MerchantFundFlowTransactionType.A_ORDER_RESELL_FEE_INCOME, parentId);
                merchantFundRepository.save(distributorMerchantFund);

                MarketOrder marketOrder = marketOrderRepository.findByOrderNum(supplierMerchantOrder.getMarketOrderNum());

                // 修改分销市场订单状态
                marketOrder.setStatus(OrderStatus.FINISHED);
                marketOrderRepository.save(marketOrder);
                distributorResellFee = this.mallFundFrozenSubtract(mallFund, mallOrder, distributorPacketResellFee, FundTransactionFlow.SPLIT, MallFundFlowTransactionType.RESELL_FEE_EXPEND, parentMallFundFlow.getParentId());

            }

            // 返利处理
            if (supplierMerchantOrderItem.getPathType() == B2C2C) {
                // 分享返利金额
                BigDecimal shareFee = supplierMerchantOrderItem.getShareFee();
                // 分享返利比率
                BigDecimal shareFeeRates = BigDecimalUtils.divide(new BigDecimal(supplierMerchantOrderItem.getShareRate()), BigDecimal.valueOf(100));

                isEnough = createEnoughToDeductionRecord(lestOrderAmount, shareFee, isEnough, supplierMerchantFund, supplierMerchantOrder, parentId, MerchantFundFlowTransactionType.A_ORDER_SHARE_FEE_EXPEND);
                lestOrderAmount = lestOrderAmount.subtract(shareFee);


                // 购买者
                BigDecimal shareCustomerShareFee = shareFee.multiply(shareFeeRates).setScale(2, BigDecimal.ROUND_HALF_UP); // 分享者分享返利
                BigDecimal buyCustomerShareFee = shareFee.subtract(shareCustomerShareFee);// 购买者分享返利

                // 分享者资金 分享返利收入
                Customer shareCustomer = customerRepository.findOne(supplierMerchantOrderItem.getSharerId());
                CustomerFund shareCustomerFund = customerFundRepository.findOne(shareCustomer.getCustomerFundId());
                shareCustomerFund = this.customerFundAvailableAmountAdd(shareCustomerFund, mallOrder, shareCustomerShareFee);
                customerFundRepository.save(shareCustomerFund);
                this.mallFundFrozenSubtract(mallFund, mallOrder, shareCustomerShareFee, FundTransactionFlow.SPLIT, MallFundFlowTransactionType.SHARER_FEE_EXPEND, parentMallFundFlow.getParentId());

                // 购买者资金 分享返利收入
                Customer buyCustomer = customerRepository.findByIdAndMallId(mallOrder.getCustomerId(), mallOrder.getMallId());
                CustomerFund buyCustomerFund = customerFundRepository.findOne(buyCustomer.getCustomerFundId());
                buyCustomerFund = this.customerFundAvailableAmountAdd(buyCustomerFund, mallOrder, buyCustomerShareFee);
                customerFundRepository.save(buyCustomerFund);
                this.mallFundFrozenSubtract(mallFund, mallOrder, buyCustomerShareFee, FundTransactionFlow.SPLIT, MallFundFlowTransactionType.BUYER_FEE_EXPEND, parentMallFundFlow.getParentId());
                merchantIncome = merchantIncome.subtract(shareFee);


            } else if (supplierMerchantOrderItem.getPathType() == B2D2C2C) {

                Long productId = supplierMerchantOrderItem.getProductId();
                Product product = merchantProductRepository.findByMarketIdAndMerchantId(productId, distributorMerchantOrder.getMerchantId());
                MerchantOrderItem distributorMerchantOrderItem = merchantOrderItemRepository.findByMarketOrderNumAndMerchantRoleAndProductId(distributorMerchantOrder.getMarketOrderNum(), MerchantOrderMerchantRole.DISTRIBUTOR, product.getId());

                BigDecimal shareFee = distributorMerchantOrderItem.getShareFee().setScale(2, BigDecimal.ROUND_HALF_UP);
                // 分享返利比率
                BigDecimal shareFeeRates = BigDecimalUtils.divide(new BigDecimal(distributorMerchantOrderItem.getShareRate()), BigDecimal.valueOf(100));

                MerchantFund distributorMerchantFund = merchantFundRepository.findOne(distributorMerchantOrder.getMerchantFundId());

                // 分商家订单结算 分享返利支出
                this.merchantFundAvailableAmount(distributorMerchantFund, distributorMerchantOrder, shareFee, null, FundTransactionFlow.EXPEND, MerchantFundFlowTransactionType.A_ORDER_SHARE_FEE_EXPEND, parentId);
                merchantFundRepository.save(distributorMerchantFund);

                // 购买者
                BigDecimal shareCustomerShareFee = shareFee.multiply(shareFeeRates).setScale(2, BigDecimal.ROUND_HALF_UP); // 分享者分享返利
                BigDecimal buyCustomerShareFee = shareFee.subtract(shareCustomerShareFee);// 购买者分享返利

                // 分享者资金 分享返利收入
                Customer shareCustomer = customerRepository.findOne(distributorMerchantOrderItem.getSharerId());
                CustomerFund shareCustomerFund = customerFundRepository.findOne(shareCustomer.getCustomerFundId());
                shareCustomerFund = this.customerFundAvailableAmountAdd(shareCustomerFund, mallOrder, shareCustomerShareFee);
                customerFundRepository.save(shareCustomerFund);
                this.mallFundFrozenSubtract(mallFund, mallOrder, shareCustomerShareFee, FundTransactionFlow.SPLIT, MallFundFlowTransactionType.SHARER_FEE_EXPEND, parentMallFundFlow.getParentId());

                // 购买者资金 分享返利收入
                Customer buyCustomer = customerRepository.findByIdAndMallId(mallOrder.getCustomerId(), mallOrder.getMallId());
                CustomerFund buyCustomerFund = customerFundRepository.findOne(buyCustomer.getCustomerFundId());
                buyCustomerFund = this.customerFundAvailableAmountAdd(buyCustomerFund, mallOrder, buyCustomerShareFee);
                customerFundRepository.save(buyCustomerFund);
                this.mallFundFrozenSubtract(mallFund, mallOrder, buyCustomerShareFee, FundTransactionFlow.SPLIT, MallFundFlowTransactionType.BUYER_FEE_EXPEND, parentMallFundFlow.getParentId());
                mallExpendSplitResellFee = mallExpendSplitResellFee.subtract(shareFee);
                if (distributorResellFee != null) {
                    distributorResellFee.setOperationAmount(mallExpendSplitResellFee);
                    mallFundFlowRepository.save(distributorResellFee);
                }
                merchantIncome = merchantIncome.subtract(shareFee);

                // 分享返利金额

            }

            BigDecimal itemServiceFee = supplierMerchantOrderItem.getDiscountAmount().multiply(mallServiceFeeRates).setScale(2, BigDecimal.ROUND_HALF_UP);
            feeType = MerchantFundFlowTransactionType.A_ORDER_SERVICE_FEE_EXPEND;
            isEnough = createEnoughToDeductionRecord(lestOrderAmount, itemServiceFee, isEnough, supplierMerchantFund, supplierMerchantOrder, parentId, feeType);
            log.info("===========+{}+===========>serviceFee:{},merchantIncome:{},itemServiceFee:{},lestOrderAmount:{}", 1, serviceFee, merchantIncome, itemServiceFee, lestOrderAmount);
            lestOrderAmount = lestOrderAmount.subtract(itemServiceFee);
            log.info("===========+{}+===========>serviceFee:{},merchantIncome:{},itemServiceFee:{},lestOrderAmount:{}", 2, serviceFee, merchantIncome, itemServiceFee, lestOrderAmount);

        }

        if (!isEnough) {
            if (lestOrderAmount.compareTo(BigDecimal.valueOf(0)) == -1) {
                lestOrderAmount = new BigDecimal(Math.abs(lestOrderAmount.doubleValue()));
                this.merchantFundAvailableAmount(supplierMerchantFund, supplierMerchantOrder, lestOrderAmount, null, FundTransactionFlow.EXPEND, MerchantFundFlowTransactionType.A_ORDER_SERVICE_FEE_ARREARS_EXPEND, parentId);
            }
        }

        this.mallFundFrozenSubtract(mallFund, mallOrder, merchantIncome.subtract(serviceFee), FundTransactionFlow.SPLIT, MallFundFlowTransactionType.F_MERCHANT_SETTLEMENT, parentMallFundFlow.getParentId());
        // 现金券
        this.cashCouponSurplusAmount(mallOrder, mallFund);

        mallFundRepository.save(mallFund); // 最终保存平台资金
    }

    /**
     *
     * @param lestOrderAmount
     * @param deductions
     * @param isEnough
     * @param supplierMerchantFund
     * @param supplierMerchantOrder
     * @param parentId
     * @param feeType
     * @return
     */
    public boolean createEnoughToDeductionRecord(BigDecimal lestOrderAmount, BigDecimal deductions, boolean isEnough, MerchantFund supplierMerchantFund, MerchantOrder supplierMerchantOrder, Long parentId, MerchantFundFlowTransactionType feeType) {


        if (lestOrderAmount.compareTo(deductions) == 1) {
            log.info("lestOrderAmount:{},deductions:{},feeType:{}", lestOrderAmount, deductions, feeType.toString());
            this.merchantFundAvailableAmount(supplierMerchantFund, supplierMerchantOrder, deductions, null, FundTransactionFlow.EXPEND, feeType, parentId);

        } else {
            if (isEnough) {
                log.info("isEnough:{}", isEnough);
                isEnough = false;
                this.merchantFundAvailableAmount(supplierMerchantFund, supplierMerchantOrder, lestOrderAmount, null, FundTransactionFlow.EXPEND, feeType, parentId);
            }

        }

        return isEnough;

    }

    /**
     * 平台冻结资金减
     *
     * @param mallFund        平台资金
     * @param mallOrder       平台订单
     * @param operationAmount 操作金额
     * @return
     */
    private MallFundFlow mallFundFrozenSubtract(MallFund mallFund, MallOrder mallOrder, BigDecimal operationAmount, FundTransactionFlow fundTransactionFlow, MallFundFlowTransactionType mallFundFlowTransactionType, Long mallFundFlowId) {
        MallFundFlow frozenMallFundFlow = MallFundFlowHelper.SINGLEONE.create(mallFund, mallOrder.getOrderNum(), BigDecimal.valueOf(0), operationAmount, operationAmount, fundTransactionFlow, mallFundFlowTransactionType);
        frozenMallFundFlow.setParentId(mallFundFlowId);
        frozenMallFundFlow = mallFundFlowRepository.save(frozenMallFundFlow);
        if (mallFundFlowId == null) {
            frozenMallFundFlow.setParentId(frozenMallFundFlow.getId());
            mallFundFlowRepository.save(frozenMallFundFlow);
        }
        if (fundTransactionFlow != FundTransactionFlow.SPLIT) {
            this.packageMallFund(mallFund, frozenMallFundFlow);
        }
        return frozenMallFundFlow;
    }

    /**
     * 平台可用资金加
     *
     * @param mallFund        平台资金
     * @param mallOrder       平台订单
     * @param operationAmount 操作金额
     */
    private MallFundFlow mallFundAvailableAmountAdd(MallFund mallFund, MallOrder mallOrder, BigDecimal operationAmount, FundTransactionFlow fundTransactionFlow, MallFundFlowTransactionType mallFundFlowTransactionType, Long mallFundFlowId) {
        MallFundFlow availableMallFundFlow = MallFundFlowHelper.SINGLEONE.create(mallFund, mallOrder.getOrderNum(), operationAmount, BigDecimal.valueOf(0), operationAmount, fundTransactionFlow, mallFundFlowTransactionType);
        availableMallFundFlow.setParentId(mallFundFlowId);
        availableMallFundFlow = mallFundFlowRepository.save(availableMallFundFlow);
        if (mallFundFlowId == null) {
            availableMallFundFlow.setParentId(availableMallFundFlow.getId());
            mallFundFlowRepository.save(availableMallFundFlow);
        }
        if (fundTransactionFlow != FundTransactionFlow.SPLIT) {
            this.packageMallFund(mallFund, availableMallFundFlow);
        }
        return availableMallFundFlow;
    }

    /**
     * 设置平台资金
     *
     * @param mallFund
     * @param mallFundFlow
     */
    private void packageMallFund(MallFund mallFund, MallFundFlow mallFundFlow) {
        mallFund.setAvailableAmount(mallFundFlow.getAvailableAmount());
        mallFund.setFrozen(mallFundFlow.getFrozen());
        mallFund.setTotalAmount(mallFundFlow.getTotalAmount());
    }

    /**
     * 商家可用资金 操作
     *
     * @param merchantFund    商家资金
     * @param merchantOrder   商家订单
     * @param operationAmount 操作金额
     * @return
     */
    private MerchantFundFlow merchantFundAvailableAmount(MerchantFund merchantFund, MerchantOrder merchantOrder, BigDecimal operationAmount, Long verifyCount, FundTransactionFlow fundTransactionFlow, MerchantFundFlowTransactionType merchantFundFlowTransactionType, Long merchantFundFlowId) {
        MerchantFundFlow incomeMerchantFundFlow = baseMerchantFundFlowHelper.create(merchantFund, merchantOrder, operationAmount, BigDecimal.valueOf(0), operationAmount, verifyCount, fundTransactionFlow, merchantFundFlowTransactionType);
        log.info("======================>商家可用资金 操作incomeMerchantFundFlow:{}", incomeMerchantFundFlow);
        incomeMerchantFundFlow.setParentId(merchantFundFlowId);
        incomeMerchantFundFlow = merchantFundFlowRepository.save(incomeMerchantFundFlow);
        if (merchantFundFlowId == null) {
            incomeMerchantFundFlow.setParentId(incomeMerchantFundFlow.getId());
            merchantFundFlowRepository.save(incomeMerchantFundFlow);
        }
        this.packageMerchantFund(merchantFund, incomeMerchantFundFlow);
        return incomeMerchantFundFlow;
    }

    /**
     * 设置商家资金
     *
     * @param merchantFund
     * @param merchantFundFlow
     */
    private void packageMerchantFund(MerchantFund merchantFund, MerchantFundFlow merchantFundFlow) {
        merchantFund.setFrozen(merchantFundFlow.getFrozen());
        merchantFund.setAvailableAmount(merchantFundFlow.getAvailableAmount());
        merchantFund.setTotalAmount(merchantFundFlow.getTotalAmount());
    }


    /**
     * 客户可用资金加
     *
     * @param customerFund
     * @param mallOrder
     * @param operationAmount
     * @return
     */
    private CustomerFund customerFundAvailableAmountAdd(CustomerFund customerFund, MallOrder mallOrder, BigDecimal operationAmount) {
        CustomerFundFlow customerFundFlow = CustomerFundFlowHelper.SINGLEONE.create(customerFund, mallOrder, operationAmount, BigDecimal.valueOf(0), operationAmount, FundTransactionFlow.INCOME, CustomerFundFlowTransactionType.SHARE_FEE, "");
        customerFundFlow = customerFundFlowRepository.save(customerFundFlow);
        this.packageCustomerFund(customerFund, customerFundFlow);
        return customerFund;
    }

    /**
     * 设置客户资金
     *
     * @param customerFund
     * @param customerFundFlow
     */
    private void packageCustomerFund(CustomerFund customerFund, CustomerFundFlow customerFundFlow) {
        customerFund.setFrozen(customerFundFlow.getFrozen());
        customerFund.setAvailableAmount(customerFundFlow.getAvailableAmount());
        customerFund.setTotalAmount(customerFundFlow.getTotalAmount());
    }

    /**
     * 更新平台订单状态
     *
     * @param mallOrder 平台订单
     */
    private void updateMallOrderStatus(MallOrder mallOrder) {
        // 判断平台订单下所有商户订单是否全部结算完,如果是平台订单需要修改订单状态
        List<MerchantOrder> merchantOrderList = merchantOrderRepository.findByMallOrderIdAndMallId(mallOrder.getId(), mallOrder.getMallId());
        boolean isAllFinished = merchantOrderList.stream().allMatch(merchantOrder -> merchantOrder.getStatus() == OrderStatus.FINISHED);
        if (isAllFinished) {
            mallOrder.setStatus(MallOrderStatus.FINISHED);
            mallOrderRepository.save(mallOrder);
        }
    }


    /**
     * 当如果使用现金券，并且现金券还有余额 需要把冻结资金 转换  可用资金
     *
     * @param mallOrder
     * @param mallFund
     */
    private void cashCouponSurplusAmount(MallOrder mallOrder, MallFund mallFund) {
        if (mallOrder.getCashCouponSurplusAmount().compareTo(BigDecimal.ZERO) == 1) {
            List<MerchantOrder> merchantOrderList = merchantOrderRepository.findByMallOrderIdAndMallId(mallOrder.getId(), mallOrder.getMallId());
            boolean isAllFinished = merchantOrderList.stream().filter(merchantOrder -> merchantOrder.getMerchantRole() != MerchantOrderMerchantRole.DISTRIBUTOR).allMatch(merchantOrder -> merchantOrder.getStatus() == OrderStatus.FINISHED);
            // 所有订单完成后,礼包开始结算
            if (isAllFinished) {
                // 冻结资金减
                MallFundFlow frozenMallFundFlow = this.mallFundFrozenSubtract(mallFund, mallOrder, mallOrder.getCashCouponSurplusAmount(), FundTransactionFlow.EXPEND, MallFundFlowTransactionType.F_CASH_COUPON_SURPLUS_SUCCESS_FROZEN_EXPEND, null);
                MallFundHelper.SINGLEONE.calculationMallFundAmount(mallFund, frozenMallFundFlow.getFrozen(), frozenMallFundFlow.getAvailableAmount());
                // 可用资金加
                MallFundFlow availableMallFundFlow = this.mallFundAvailableAmountAdd(mallFund, mallOrder, mallOrder.getCashCouponSurplusAmount(), FundTransactionFlow.INCOME, MallFundFlowTransactionType.F_CASH_COUPON_SURPLUS_SUCCESS_INCOME, null);
                MallFundHelper.SINGLEONE.calculationMallFundAmount(mallFund, availableMallFundFlow.getFrozen(), availableMallFundFlow.getAvailableAmount());
            }
        }
    }

}
